﻿using Engine;
using Engine.Graphics;
using Game;

namespace SAGhoul.Blocks
{
    public class SAGArtifactBlock : Block
    {
        public BlockMesh m_handleMesh = new();
        public BlockMesh m_chunkUnlitMesh = new();
        public BlockMesh m_chunkLitMesh = new();
        public BlockMesh m_ringMesh = new();
        public BlockMesh[] m_cubeMeshes = new BlockMesh[4];
        private Texture2D m_texture;

        public override void Initialize()
        {
            m_texture = ContentManager.Get<Texture2D>("Textures/Trophy");
            Model model = ContentManager.Get<Model>("Models/SAGArtifact");
            Matrix transform_Handle = BlockMesh.GetBoneAbsoluteTransform(model.FindMesh("Handle").ParentBone) * Matrix.CreateTranslation(0f, -0.75f, 0f);
            m_handleMesh.AppendModelMeshPart(model.FindMesh("Handle").MeshParts[0], transform_Handle, makeEmissive: false, flipWindingOrder: false, doubleSided: false, flipNormals: false, Color.White);
            
            Matrix transform_Chunk = BlockMesh.GetBoneAbsoluteTransform(model.FindMesh("Chunk").ParentBone) * transform_Handle;
            m_chunkUnlitMesh.AppendModelMeshPart(model.FindMesh("Chunk").MeshParts[0], transform_Chunk, makeEmissive: false, flipWindingOrder: false, doubleSided: false, flipNormals: false, Color.White);
            m_chunkLitMesh.AppendModelMeshPart(model.FindMesh("Chunk").MeshParts[0], transform_Chunk, makeEmissive: true, flipWindingOrder: false, doubleSided: false, flipNormals: false, Color.White);

            Matrix transform_Ring = BlockMesh.GetBoneAbsoluteTransform(model.FindMesh("Ring").ParentBone) * transform_Handle;
            m_ringMesh.AppendModelMeshPart(model.FindMesh("Ring").MeshParts[0], transform_Ring, makeEmissive: false, flipWindingOrder: false, doubleSided: false, flipNormals: false, Color.White);

            for(int i = 0; i < m_cubeMeshes.Length; i++)
			{
                m_cubeMeshes[i] = new BlockMesh();
                ModelMesh modelMesh = model.FindMesh("Cube" + i.ToString(), false);
                if(modelMesh == null)
                    continue;
                Matrix transform_Cubei = BlockMesh.GetBoneAbsoluteTransform(modelMesh.ParentBone) * transform_Handle;
                m_cubeMeshes[i].AppendModelMeshPart(modelMesh.MeshParts[0], transform_Cubei, makeEmissive: i % 2 == 0, flipWindingOrder: false, doubleSided: false, flipNormals: false, Color.White);
            }
            base.Initialize();
        }

        public override void DrawBlock(PrimitivesRenderer3D primitivesRenderer, int value, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
        {
            BlocksManager.DrawMeshBlock(primitivesRenderer, m_handleMesh, m_texture, color, 2f * size, ref matrix, environmentData);
            SubsystemSAGArtifactBlockBehavior subsystemSAGArtifactBlockBehavior = environmentData.SubsystemTerrain?.Project.FindSubsystem<SubsystemSAGArtifactBlockBehavior>();
            if (subsystemSAGArtifactBlockBehavior == null)
                return;
            bool isRunning = subsystemSAGArtifactBlockBehavior.IsRunning;
            var time = Time.FrameStartTime;
            float rotation = (float)(time * 0.5f) % (2f * MathUtils.PI);
            float offsetY = (float)MathUtils.Sin(time) * 0.03f + 0.03f;

            Matrix matrix_chunk = Matrix.CreateRotationY(rotation) * Matrix.CreateTranslation(0, offsetY, 0) * matrix;
            Matrix matrix_ring = Matrix.CreateRotationY(rotation * (isRunning ? 25f : -5f)) * matrix;
            BlocksManager.DrawMeshBlock(primitivesRenderer, isRunning ? m_chunkLitMesh : m_chunkUnlitMesh, m_texture, color, 2f * size, ref matrix_chunk, environmentData);
            BlocksManager.DrawMeshBlock(primitivesRenderer, m_ringMesh, m_texture, color, 2f * size, ref matrix_ring, environmentData);
            for (int i = 0; i < m_cubeMeshes.Length; i++)
			{
                Vector3 translation;
                //float rotationi;
                if (i % 2 == 0)
				{
                    translation = new Vector3(offsetY, -0.5f * offsetY, 0);
                    //rotationi = rotation * 0.66f;
                }
				else
				{
                    translation = new Vector3(0, 0.33f * offsetY, -0.75f * offsetY);
                    //rotationi = rotation * -0.8f;
                }
                Matrix matrix_cubei = /*Matrix.CreateRotationY(rotationi) **/ Matrix.CreateTranslation(translation) * matrix;
                BlocksManager.DrawMeshBlock(primitivesRenderer, m_cubeMeshes[i], m_texture, color, 2f * size, ref matrix_cubei, environmentData);
            }
        }

		public override int GetDamageDestructionValue(int value)
		{
			return typeof(SAGBrokenArtifactBlock).BlockIndex();
		}
		public override bool IsSwapAnimationNeeded(int oldValue, int newValue)
		{
            int oldValueWithoutDamage = SetDamage(oldValue, 0);
            int newValueWithoutDamage = SetDamage(newValue, 0);
			return oldValueWithoutDamage != newValueWithoutDamage;
		}
		public override void GenerateTerrainVertices(BlockGeometryGenerator generator, TerrainGeometry geometry, int value, int x, int y, int z)
        {
        }

    }
}
